package com.fingard.dsp.bank.directbank.cmb01.receiptpro;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.fingard.constant.Format;
import com.fingard.diagnostics.LogHelper;
import com.fingard.dsp.bank.dbobj.receipt.ReceiptData;
import com.fingard.dsp.bank.dbobj.receipt.ReceiptDataHelper;
import com.fingard.dsp.bank.directConfig.ReceiptProConfig;
import com.fingard.dsp.bank.directConfig.TaskTimerSet;
import com.fingard.dsp.bank.directbank.cmb01.CMB01Base;
import com.fingard.dsp.bank.sepro.ReceiptPro;
import com.fingard.dsp.task.DelayCounter;
import com.fingard.dsp.task.command.SyncReceipt;
import com.fingard.io.FileHelper;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XmlTextWriter;

import com.fingard.FGBiz;

public class CMB01TaskReceiptPro extends CMB01Base{
	private String logCode = "CMB01"+File.separator+"TaskReceiptPro";
	private TaskTimerSet timerSet;
	private ReceiptProConfig proConfig;
	
	private static DelayCounter delayCounter = new DelayCounter(45, 2);//最大延时45分钟，按平方计算，即4次=4*4=16分钟
	public static void resetDelayCounter(){
		delayCounter.resetZeroCount();
	}
	
	public void downReceipt(TaskTimerSet pTimerSet){
		try {
			timerSet = pTimerSet;
			
			if(delayCounter.isDelay()){
				return;
			}
			
            int succDownCount = downFiles();
			
			if(succDownCount == 0){
				delayCounter.increaseZeroCount();
				long delayMins = delayCounter.getDelayMinutes();
				String aLog = "成功个数为0，";
				if(delayMins>0){
					aLog+="下次执行将增加延时"+delayMins+"分钟，";
				}
				aLog+="预计下次执行时间："+Format.DateTimeMinFormat.format(delayCounter.getExpectNextExecTime());
				FGBiz.logTrace.info(logCode, aLog);
			}else{
				delayCounter.resetZeroCount();
				SyncReceipt.resetDelayCounter();//同步任务重新计数延时
			}
		}catch (Exception e) {
			FGBiz.logTrace.exception(logCode, e);
		}
	}
	
	private int downFiles() throws Exception{
		if (StringHelper.isNullOrEmpty(bankFront.bankReceiptMainDir)) {
			FGBiz.logTrace.error(logCode, "未配置bankReceiptMainDir");
            return 0;
        }
        File receiptDir = new File(bankFront.bankReceiptMainDir);
        if (!receiptDir.exists()) {
        	FGBiz.logTrace.error(logCode, "不存在招行回单目录" + bankFront.bankReceiptMainDir);
            return 0;
        }
        
		File[] receiptFiles = receiptDir.listFiles();
		if(receiptFiles.length == 0){
			FGBiz.logTrace.info(logCode, "回单目录" + bankFront.bankReceiptMainDir+"下暂无文件产生");
            return 0;
		}
		int totalFileCount = 0;//总文件个数
        int needDownCount = 0;//总需要保存的个数
		int succDownCount = 0;//新保存成功的个数
		int failDownCount = 0;//保存失败的个数
		int jpgFileCount = 0;//.jpg文件个数
		int validFileCount = 0;//有效的文件个数
		int errNameCount = 0;//文件名不符合的个数
        int canNotFindData = 0;//找不到回单数据个数
        int duplicateCount = 0;//已经下载的个数
        int timeTooClose = 0;//生成时间太近
		proConfig = ReceiptPro.getReceiptProConfig();
		boolean outDtLog = delayCounter.getOutDetailLog(proConfig, timerSet);
		
		StringBuilder sbTooClose = new StringBuilder();
        StringBuilder sbErrFileName = new StringBuilder();//记录格式有问题的文件名
        StringBuilder sbCanNotFind = new StringBuilder();//找不到回单数据的文件名
        StringBuilder sbFailDown = new StringBuilder();//复制失败的文件名

        //查回单禁用第一步SDKCSFDFBRT，数据量很大时第一步会查不回
        boolean disableReceiptFirstStep = this.getBankConfig().getValueAsBool("disableReceiptFirstStep");
        
        ArrayList<File> listToDelete = new ArrayList<File>();
        HashMap<String, ReceiptDataHelper> mapReceiptHelper = new HashMap<String, ReceiptDataHelper>();
        try{
        	for (File receiptFile : receiptFiles) {//遍历招行前置回单目录
        		if(!receiptFile.isFile()){
        			continue;
        		}
        		totalFileCount++;
                String eachName = receiptFile.getName();
                if (eachName.toLowerCase().endsWith(".jpg")) {
                	jpgFileCount++;
                    Date lastMdDate = new Date(receiptFile.lastModified());
                    double diffSecs = DateHelper.getDifferSecs(new Date(), lastMdDate);
                    if (diffSecs < 5) {//小于5秒的先不传
                    	timeTooClose++;
                    	if(outDtLog){
                    		sbTooClose.append(eachName+"\r\n");
                    	}
                        continue;
                    }
                    String[] finfo = eachName.split("_");
                    if (finfo.length >= 3) {
                    	validFileCount++;
                    	try{
                    		String actNum = finfo[0];//账号
                            String[] filedates = finfo[1].split("-");
                            String fdate = filedates[0];//日期
                            Date busDate = DateHelper.convertToDateExtra(fdate);
                            String[] fileIstNbr = finfo[2].split("\\.");
                            String bkIstNbr = fileIstNbr[0];//打印实例号
                            ReceiptDataHelper receiptHelper = null;
                            if(!mapReceiptHelper.containsKey(fdate)){
                            	receiptHelper = new ReceiptDataHelper(reqHeader.tenant, busDate);
                            	mapReceiptHelper.put(fdate, receiptHelper);
                            }else{
                            	receiptHelper = mapReceiptHelper.get(fdate);
                            }
                            String bkReceiptNo = "";
                            if(finfo.length>=4){
                            	String[] fileReceiptNo = finfo[3].split("\\.");
                            	bkReceiptNo = fileReceiptNo[0];
                            }
                            //取得数据
                            ReceiptData aData = receiptHelper.loadFromDbByIstNbr(actNum, bkIstNbr);
                            if(aData == null){
                            	if(disableReceiptFirstStep){
                                	if(StringHelper.isNullOrEmpty(bkReceiptNo)){
                                		canNotFindData++;
                                    	if(outDtLog){
                                    		sbCanNotFind.append(eachName+"\r\n");
                                    	}
                                    	FGBiz.logTrace.error(logCode, "从文件名"+eachName+"中提取不到回单关联号");
                                    	continue;
                                	}
                                	//如果禁用了回单数据查询，这里直接添加数据
                                	ReceiptData eachData = new ReceiptData();
                                	eachData.ownAct = actNum;
                                	eachData.bank = "308";
                                	eachData.istNbr = bkIstNbr;
                                	eachData.srcSys = "CMB01";
                                    eachData.bank = "308";
                                    eachData.receiptNo = bkReceiptNo;
                                    eachData.downState = "1";
                                    eachData.setBusDate(busDate);
                                    try{
                                    	int inRe = receiptHelper.insertIfNotExist(eachData, true);
                                    	if(inRe>0){
                                    		aData = eachData;
                                    	}else{
                                    		FGBiz.logTrace.error(logCode, "新增"+eachName+"的回单数据不成功，影响行数："+inRe);
                                    		continue;
                                    	}
                                    }catch(Exception ex){
                                    	FGBiz.logTrace.exception(logCode, ex, eachName);
                                    	continue;
                                    }
                            	}else{
                            		//未找到回单数据
                                	canNotFindData++;
                                	if(outDtLog){
                                		sbCanNotFind.append(eachName+"\r\n");
                                	}
                                	continue;
                            	}
                            }
                            if("2".equals(aData.downState)){
                            	//该回单已经下载
                            	duplicateCount++;
                            	listToDelete.add(receiptFile);
                            	continue;
                            }
                            needDownCount++;
                            try{
                            	//按月建目录存下载的压缩文件
                        		String saveDirPath = proConfig.getSaveSubDir(reqHeader, busDate) + File.separator + fdate + File.separator + actNum;
                                String saveFilePath = saveDirPath+File.separator+eachName;
                                aData.downState="3";//先置为失败
                                
                                aData.downTime=new Date();
                        		aData.srcFile = eachName;
                        		aData.localFile = proConfig.getPathRelativeToMain(saveFilePath);
                        		
                        		File destFile = new File(saveFilePath);
                        		if(destFile.exists() && destFile.length() != receiptFile.length()){
                        			destFile.delete();
                        		}
                        		destFile = new File(saveFilePath);
                        		if(!destFile.exists()){
                        			FileHelper.copyFile(receiptFile, destFile);
                        			aData.downInfo="复制成功";
                        		}else{
                        			aData.downInfo="文件之前已保存成功";
                        		}
                        		if(destFile.exists()){
                        			aData.downState="2";
                        		}else{
                        			aData.downInfo="复制失败";
                        		}
                            }catch(Exception ex){
                            	FGBiz.logTrace.exception(logCode, ex, "复制文件"+eachName);
                            	aData.downInfo = LogHelper.getStackTrace(ex);
                            }
                            int rowsAff = receiptHelper.updateDownState(aData);
                			if(rowsAff > 0){
                				if("2".equals(aData.downState)){
                					succDownCount++;
                					listToDelete.add(receiptFile);
                				}else{
                					failDownCount++;
                					if(outDtLog){
                						sbFailDown.append(eachName+"\r\n");
                					}
                				}
                			}else{
                				FGBiz.logTrace.error(logCode, "urid为" + aData.urid + "，回单关联号为"+aData.receiptNo+"，文件名为" + eachName + "，更新downState为"+aData.downState+"，影响行数："+rowsAff);
                			}
                    	}catch(Exception ex){
                    		FGBiz.logTrace.exception(logCode, ex, eachName);
                    	}
                    } else {
                    	errNameCount++;
                    	if(outDtLog){
                    		sbErrFileName.append(eachName+"\r\n");
                    	}
                    }
                }
            }
        }catch(Exception ex){
        	FGBiz.logTrace.exception(logCode, ex);
        }finally{
        	for(Map.Entry<String, ReceiptDataHelper> eachEntry : mapReceiptHelper.entrySet()){
        		ReceiptDataHelper aHelper = eachEntry.getValue();
        		if(aHelper!=null){
        			aHelper.close();
        		}
        	}
        }
        StringBuilder sbSum = new StringBuilder();
        sbSum.append("遍历"+totalFileCount+"个文件\r\n");
        sbSum.append("有"+jpgFileCount+"个jpg文件，其中有效"+validFileCount+"个，文件名格式无效"+errNameCount+"个\r\n");
        if(canNotFindData>0){
        	sbSum.append("有"+canNotFindData+"个文件找不到回单数据，如果文件有效，请联系技术支持进行排查\r\n");
        }
        if(timeTooClose>0){
        	sbSum.append("有"+timeTooClose+"个文件刚生成不到5秒，等下一次轮询处理\r\n");
        }
        if(duplicateCount>0){
        	sbSum.append("有"+duplicateCount+"个文件之前已经保存成功，等待删除\r\n");
        }
        sbSum.append("本次需保存"+needDownCount+"个，保存成功"+succDownCount+"个，保存失败"+failDownCount+"个\r\n");
        
        int delCount = 0;
        int timeNotUpCount = 0;//删除时间未到
        for (File delFile : listToDelete) {
            try {
            	Date mdDate = new Date(delFile.lastModified());
            	double chkHours = DateHelper.getDifferHours(new Date(), mdDate);
            	if(chkHours>24){//超过24小时再删
                    delFile.delete();
                    delCount++;
            	}else{
            		timeNotUpCount++;
            	}
            } catch (Exception ex) {
            	FGBiz.logTrace.exception(logCode, ex, "删除"+delFile.getName());
            }
        }
        sbSum.append("成功删除" + delCount + "个文件\r\n");
        if(timeNotUpCount>0){
        	sbSum.append("有" + timeNotUpCount + "个文件需等到离创建时间24小时后再删除\r\n");
        }
        FGBiz.logTrace.info(logCode, sbSum.toString());
        
        if(sbTooClose.length()>0){
        	FGBiz.logTrace.info(logCode, "刚生成的（生成时间小于5秒，可能未结束，等待下次轮询处理）文件列表：\r\n"+sbTooClose.toString());
        }
        if(sbErrFileName.length()>0){
        	FGBiz.logTrace.info(logCode, "文件名格式有问题的文件列表：\r\n"+sbErrFileName.toString());
        }
        if(sbCanNotFind.length()>0){
        	FGBiz.logTrace.info(logCode, "找不到回单数据的文件列表：\r\n"+sbCanNotFind.toString());
        }
        if(sbFailDown.length()>0){
        	FGBiz.logTrace.info(logCode, "复制失败的文件列表：\r\n"+sbFailDown.toString());
        }
        
		return succDownCount;
	}
}
